/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.cvut.fel.taskpro.view.controller;

import cz.cvut.fel.taskpro.business.imanager.IAssignmentBusiness;
import cz.cvut.fel.taskpro.business.imanager.IUserBusiness;
import cz.cvut.fel.taskpro.business.support.BusinessRuleException;
import cz.cvut.fel.taskpro.business.support.TaskProException;
import cz.cvut.fel.taskpro.data.entity.Assignment;
import cz.cvut.fel.taskpro.data.entity.Assignment.Type;
import cz.cvut.fel.taskpro.data.entity.AssignmentSubmit;
import cz.cvut.fel.taskpro.data.entity.TemplateFile;
import cz.cvut.fel.taskpro.data.entity.Version;
import cz.cvut.fel.taskpro.data.entity.VersionFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

/**
 * Controller which provide student sending task and loading all task to submit
 * including filtering. This class ic session scope and is called as
 * studentTaskBean.
 *
 * @author Tom
 * @version 1.0.0. beta
 */
@ManagedBean(name = "studentTaskBean")
@SessionScoped
public class StudentTask extends AbstractFileController implements Serializable {

    private boolean submitTask;
    private boolean unSubmitTask;
    private List<Assignment.Type> selectedTypes;
    private List<Assignment.Type> types;
    private Assignment.Type[] typeOfAssignment;
    private List<Assignment> taskToSubmit;
    private List<Assignment> assignedTask;
    private Assignment taskChoosen;
    private Version versionOfTask;
    private AssignmentSubmit assignmentSubmit;
    private List<TemplateFile> templaty;
    @EJB
    private IAssignmentBusiness assignmentB;
    @EJB
    private IUserBusiness userB;

    public StudentTask() {
    }

    @PostConstruct
    public void init() {
        recognizeLogin();
    }

    /**
     * This method prepare class to submit task. This method create new
     * submitted assignment and create pre version to which will be added files
     * to submit. Then return user to submitTaskStudent.xhtml view using return
     * string value submitTaskStudent.
     *
     * @return string to redirect to page submitTaskStudent.xhtml. This return
     * exactly word submitTaskStudent
     */
    public String submitTask() {
        assignmentSubmit = new AssignmentSubmit(taskChoosen, loggedStudent);
        versionOfTask = new Version(assignmentSubmit);
        return "submitTaskStudent";
    }

    /**
     * This method remove version file from already added version files to
     * assignment submit. The remove is only localy and the file is remove only
     * from prepare assignment to submit.
     *
     * @param versionFile version file which will be removed from added version
     * files to assignment submit.
     *
     */
    public void removeFile(VersionFile versionFile) {
        List<VersionFile> addedVersionFiles = versionOfTask.getmVersionFiles();
        addedVersionFiles.remove(versionFile);
        versionOfTask.setmVersionFiles(addedVersionFiles);
        printSuccMessage("File remove:", "The file  was removed.");
    }

    /**
     * This method submit taask. Prepared assignment submit will submiteed via
     * business layer. Then new empty assignment submit will be initialize. If
     * submit will successfull then string
     * <code>welcomePageStudent</code> is returned and user will be redirected
     * to
     * <code>welcomePageStudent.xhtml</code> otherwise submitTaskStudent is
     * returned and user will be redirected to
     * <code>submitTaskStudent.xhtml</code> page.
     *
     * @return If submit will successfull then string
     * <code>welcomePageStudent</code> is returned and user will be redirected
     * to
     * <code>welcomePageStudent.xhtml</code> otherwise submitTaskStudent is
     * returned and user will be redirected to
     * <code>submitTaskStudent.xhtml</code> page.
     * @see
     * IAssignmentBusiness#submitAssignments(cz.cvut.fel.taskpro.data.entity.Version)
     */
    public String sendTask() {
        try {
            assignmentB.submitAssignments(versionOfTask);
            printSuccMessage("Submit task: ", "The task " + taskChoosen.getTemplate().getName() + ""
                    + " was successfully sended.");
            assignmentSubmit = new AssignmentSubmit(taskChoosen, loggedStudent);
            versionOfTask = new Version(assignmentSubmit);
            return "welcomePageStudent";
        } catch (BusinessRuleException e) {
            printErrMessage(e.getExceptionCode(), e.getErrorMessage());
            return "submitTaskStudent";
        } catch (TaskProException e) {
            printErrMessage(e.getExceptionCode(), e.getErrorMessage());
            return "submitTaskStudent";
        }
    }

    /**
     * This method provide version file upload. New file is parsed from
     * fileUploadEvent and then is added to existing version of task to submit.
     *
     * @param event fileUploadEvent from which will be parsed new version file.
     *
     */
    public void uploadFile(FileUploadEvent event) throws IOException {
        UploadedFile uploadedFile = event.getFile();
        InputStream stream = event.getFile().getInputstream();
        File fileAddToTask = inputStreamToFile(stream, event.getFile().getFileName());
        VersionFile fileToTask = new VersionFile();
        byte[] bytes = uploadedFile.getContents();
        fileToTask.setFileName(uploadedFile.getFileName());
        fileToTask.setFileSize(uploadedFile.getSize());
        fileToTask.setFile(bytes);
        fileToTask.setVersion(versionOfTask);
        List<VersionFile> taskes = versionOfTask.getmVersionFiles();
        if (taskes == null) {
            taskes = new ArrayList<VersionFile>();
        }
        taskes.add(fileToTask);
        versionOfTask.setmVersionFiles(taskes);
        printSuccMessage("Upload file", "File was sucessfuly uploaded. Now you can manage them.");
        printWarning("Submi task:", "To submit task you have to click on Submit task button above.");
    }

    /**
     * This method reset choosen assignment. Variable taskChoosen is reset.
     */
    public void resetChoosenAssignment() {
        taskChoosen = null;
    }

    /**
     * This method prepare class to display all assignment to submit. Business
     * layer if asked to assignment which could be submit based on loggedUser.
     * Then filter is settep up to all type (Student,Team). Stundet type
     * represents Group and Student type of assignment.
     *
     * @return redirect string taskToSubmit which redirect user to
     * <code>
     * taskToSubmit.xhtml</code>
     * @see
     * IAssignmentBusiness#getAssignmentsToSubmit(cz.cvut.fel.taskpro.data.entity.Student)
     * tA
     *
     */
    public String loadTaskToSubmit() {
        try {
            submitTask = true;
            unSubmitTask = true;
            taskToSubmit = null;
            taskChoosen = null;
            taskToSubmit = assignmentB.getAssignmentsToSubmit(loggedStudent);
            types = new ArrayList<Assignment.Type>();
            types.add(Type.STUDENT);
            types.add(Type.TEAM);
            selectedTypes = types;
        } catch (BusinessRuleException e) {
            printErrMessage(e.getExceptionCode(), e.getErrorMessage());
        }
        return "taskToSubmit";
    }

    /**
     * This function filter assignments to submit. Filter work with,
     * loggedStudent, selected types which represents type of assignent. Student
     * is group and student. Team is only team. States are only rejected and
     * submitted cause accepted assignment could not be submitted again. Boolean
     * submitTask mean if true then we want only submitted Task. Boolean
     * unSubmitTask mean if we want to in filter unsubmit task. Both combination
     * is allowed.
     *
     * @see
     * IAssignmentBusiness#getAssignmentToSubmitByContextFilter(cz.cvut.fel.taskpro.data.entity.Student,
     * java.util.List, java.util.List, boolean, boolean)
     */
    public void applyFilter() {
        List<AssignmentSubmit.State> states = new ArrayList<AssignmentSubmit.State>();
        states.add(AssignmentSubmit.State.REJECTED);
        states.add(AssignmentSubmit.State.SUBMITTED);
        taskToSubmit = assignmentB.getAssignmentToSubmitByContextFilter(loggedStudent, selectedTypes, states, submitTask, unSubmitTask);
        printSuccMessage("Filter: ", "filter has been successfully set up.");
    }

    public void loadSubmitTask() {
    }

    public List<Type> getSelectedTypes() {
        return selectedTypes;
    }

    public void setSelectedTypes(List<Type> selectedTypes) {
        this.selectedTypes = selectedTypes;
    }

    public boolean isSubmitTask() {
        return submitTask;
    }

    public void setSubmitTask(boolean submitTask) {
        this.submitTask = submitTask;
    }

    public boolean isUnSubmitTask() {
        return unSubmitTask;
    }

    public void setUnSubmitTask(boolean unSubmitTask) {
        this.unSubmitTask = unSubmitTask;
    }

    public List<Assignment.Type> getTypes() {
        return types;
    }

    public Assignment.Type[] getTypeOfAssignment() {
        return typeOfAssignment;
    }

    public void setTypeOfAssignment(Assignment.Type[] typeOfAssignment) {
        this.typeOfAssignment = typeOfAssignment;
    }

    public void setTypes(List<Assignment.Type> types) {
        this.types = types;
    }

    public List<Assignment> getTaskToSubmit() {
        return taskToSubmit;
    }

    public void setTaskToSubmit(List<Assignment> taskToSubmit) {
        this.taskToSubmit = taskToSubmit;
    }

    public AssignmentSubmit getAssignmentSubmit() {
        return assignmentSubmit;
    }

    public void setAssignmentSubmit(AssignmentSubmit assignmentSubmit) {
        this.assignmentSubmit = assignmentSubmit;
    }

    public List<Assignment> getAssignedTask() {
        return assignedTask;
    }

    public void setAssignedTask(List<Assignment> assignedTask) {
        this.assignedTask = assignedTask;
    }

    public Version getVersionOfTask() {
        return versionOfTask;
    }

    public void setVersionOfTask(Version versionOfTask) {
        this.versionOfTask = versionOfTask;
    }

    public Assignment getTaskChoosen() {
        return taskChoosen;
    }

    public void setTaskChoosen(Assignment taskChoosen) {
        this.taskChoosen = taskChoosen;
    }

    public List<TemplateFile> getTemplaty() {
        return templaty;
    }

    public void setTemplaty(List<TemplateFile> templaty) {
        this.templaty = templaty;
    }
}
